"""
可视化生成器

提供多类型图表自动生成、可视化效果优化和交互式图表支持功能
"""

import logging
import json
import base64
import io
from typing import Dict, List, Optional, Any, Tuple, Union, Callable
from dataclasses import dataclass, field
from enum import Enum
import datetime
import math
import statistics
from pathlib import Path

# 可视化相关库
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import seaborn as sns
import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
import plotly.io as pio
import numpy as np
import pandas as pd

from ..models.base_models import BaseModel
from .base_component import BaseComponent

logger = logging.getLogger(__name__)


class ChartType(Enum):
    """图表类型"""
    LINE = "line"                    # 折线图
    BAR = "bar"                      # 柱状图
    SCATTER = "scatter"              # 散点图
    PIE = "pie"                      # 饼图
    HISTOGRAM = "histogram"          # 直方图
    BOX = "box"                      # 箱线图
    VIOLIN = "violin"                # 小提琴图
    HEATMAP = "heatmap"              # 热力图
    TREEMAP = "treemap"              # 树状图
    SUNBURST = "sunburst"            # 旭日图
    RADAR = "radar"                  # 雷达图
    WATERFALL = "waterfall"          # 瀑布图
    GANTT = "gantt"                  # 甘特图
    NETWORK = "network"              # 网络图
    SANKEY = "sankey"                # 桑基图
    FUNNEL = "funnel"                # 漏斗图
    GAUGE = "gauge"                  # 仪表盘
    CANDLESTICK = "candlestick"      # K线图
    SURFACE = "surface"              # 3D表面图
    MESH = "mesh"                    # 3D网格图


class VisualizationLibrary(Enum):
    """可视化库"""
    MATPLOTLIB = "matplotlib"
    PLOTLY = "plotly"
    SEABORN = "seaborn"
    AUTO = "auto"                    # 自动选择


class OutputFormat(Enum):
    """输出格式"""
    PNG = "png"
    SVG = "svg"
    PDF = "pdf"
    HTML = "html"
    JSON = "json"
    BASE64 = "base64"


@dataclass
class ChartStyle(BaseModel):
    """图表样式配置"""
    # 颜色配置
    color_palette: List[str] = field(default_factory=lambda: [
        '#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd',
        '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf'
    ])
    background_color: str = "white"
    grid_color: str = "#e0e0e0"
    
    # 字体配置
    font_family: str = "Arial"
    font_size: int = 12
    title_font_size: int = 16
    axis_label_font_size: int = 10
    
    # 布局配置
    figure_width: int = 800
    figure_height: int = 600
    margin_top: int = 50
    margin_bottom: int = 50
    margin_left: int = 60
    margin_right: int = 50
    
    # 样式主题
    theme: str = "default"  # default, dark, minimal, academic
    
    # 交互配置
    interactive: bool = True
    show_toolbar: bool = True
    show_legend: bool = True
    
    def apply_theme(self, theme: str):
        """应用预定义主题"""
        if theme == "dark":
            self.background_color = "#2e2e2e"
            self.grid_color = "#555555"
            self.color_palette = [
                '#00d4ff', '#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4',
                '#feca57', '#ff9ff3', '#54a0ff', '#5f27cd', '#00d2d3'
            ]
        elif theme == "minimal":
            self.background_color = "#fafafa"
            self.grid_color = "#f0f0f0"
            self.color_palette = [
                '#333333', '#666666', '#999999', '#cccccc', '#000000'
            ]
        elif theme == "academic":
            self.background_color = "white"
            self.grid_color = "#e8e8e8"
            self.color_palette = [
                '#2c3e50', '#3498db', '#e74c3c', '#f39c12', '#27ae60',
                '#9b59b6', '#34495e', '#16a085', '#e67e22', '#8e44ad'
            ]
        
        self.theme = theme


@dataclass
class ChartConfig(BaseModel):
    """图表配置"""
    chart_type: ChartType = ChartType.LINE
    title: str = ""
    subtitle: str = ""
    
    # 轴配置
    x_axis_title: str = ""
    y_axis_title: str = ""
    x_axis_type: str = "linear"  # linear, log, category, date
    y_axis_type: str = "linear"
    
    # 数据配置
    x_column: str = ""
    y_column: str = ""
    color_column: Optional[str] = None
    size_column: Optional[str] = None
    group_column: Optional[str] = None
    
    # 样式配置
    style: ChartStyle = field(default_factory=ChartStyle)
    
    # 特定图表配置
    chart_specific_config: Dict[str, Any] = field(default_factory=dict)
    
    # 输出配置
    output_format: OutputFormat = OutputFormat.HTML
    library: VisualizationLibrary = VisualizationLibrary.AUTO


@dataclass
class VisualizationResult(BaseModel):
    """可视化结果"""
    success: bool = True
    error_message: str = ""
    
    # 图表信息
    chart_type: ChartType = ChartType.LINE
    library_used: VisualizationLibrary = VisualizationLibrary.PLOTLY
    
    # 输出内容
    output_data: str = ""  # 图表数据（HTML、JSON、Base64等）
    output_format: OutputFormat = OutputFormat.HTML
    file_path: Optional[str] = None
    
    # 统计信息
    data_points: int = 0
    generation_time_ms: float = 0.0
    file_size_bytes: int = 0
    
    # 质量评估
    visual_quality_score: float = 0.0
    accessibility_score: float = 0.0
    performance_score: float = 0.0
    
    def get_overall_score(self) -> float:
        """获取总体质量评分"""
        return (self.visual_quality_score + self.accessibility_score + self.performance_score) / 3


@dataclass
class ChartRecommendation(BaseModel):
    """图表推荐"""
    chart_type: ChartType = ChartType.LINE
    confidence: float = 0.0
    reason: str = ""
    
    # 推荐配置
    recommended_config: Optional[ChartConfig] = None
    
    # 适用性评分
    data_suitability: float = 0.0
    visual_effectiveness: float = 0.0
    user_preference: float = 0.0
    
    def get_total_score(self) -> float:
        """获取总评分"""
        return (self.data_suitability + self.visual_effectiveness + self.user_preference) / 3


class VisualizationGenerator(BaseComponent):
    """可视化生成器"""
    
    def get_required_configs(self) -> List[str]:
        """获取必需的配置项"""
        return []
    
    def _setup_component(self):
        """设置组件特定的初始化逻辑"""
        self.logger.info("可视化生成器初始化")
        
        # 设置matplotlib中文字体支持
        plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS', 'DejaVu Sans']
        plt.rcParams['axes.unicode_minus'] = False
        
        # 设置seaborn样式
        sns.set_style("whitegrid")
        
        # 注册图表生成函数
        self.chart_generators = {
            ChartType.LINE: self._generate_line_chart,
            ChartType.BAR: self._generate_bar_chart,
            ChartType.SCATTER: self._generate_scatter_chart,
            ChartType.PIE: self._generate_pie_chart,
            ChartType.HISTOGRAM: self._generate_histogram,
            ChartType.BOX: self._generate_box_chart,
            ChartType.VIOLIN: self._generate_violin_chart,
            ChartType.HEATMAP: self._generate_heatmap,
            ChartType.TREEMAP: self._generate_treemap,
            ChartType.SUNBURST: self._generate_sunburst,
            ChartType.RADAR: self._generate_radar_chart,
            ChartType.WATERFALL: self._generate_waterfall_chart,
            ChartType.GANTT: self._generate_gantt_chart,
            ChartType.NETWORK: self._generate_network_chart,
            ChartType.SANKEY: self._generate_sankey_chart,
            ChartType.FUNNEL: self._generate_funnel_chart,
            ChartType.GAUGE: self._generate_gauge_chart,
            ChartType.CANDLESTICK: self._generate_candlestick_chart,
            ChartType.SURFACE: self._generate_surface_chart,
            ChartType.MESH: self._generate_mesh_chart
        }
        
        # 图表推荐规则
        self.recommendation_rules = self._initialize_recommendation_rules()
        
        # 缓存生成的图表
        self.chart_cache: Dict[str, VisualizationResult] = {}
        
        self.logger.info("可视化生成器初始化完成")  
  
    def recommend_chart_type(self, 
                           data: pd.DataFrame, 
                           analysis_goal: str = "",
                           user_preferences: Dict[str, Any] = None) -> List[ChartRecommendation]:
        """
        推荐合适的图表类型
        
        Args:
            data: 数据DataFrame
            analysis_goal: 分析目标 (comparison, distribution, relationship, composition, trend)
            user_preferences: 用户偏好
            
        Returns:
            图表推荐列表，按推荐度排序
        """
        try:
            recommendations = []
            
            # 分析数据特征
            data_features = self._analyze_data_features(data)
            
            # 根据分析目标和数据特征推荐图表
            for chart_type, rules in self.recommendation_rules.items():
                score = self._calculate_recommendation_score(
                    chart_type, data_features, analysis_goal, user_preferences or {}
                )
                
                if score > 0.3:  # 只推荐评分较高的图表
                    recommendation = ChartRecommendation(
                        chart_type=chart_type,
                        confidence=score,
                        reason=self._generate_recommendation_reason(chart_type, data_features, analysis_goal),
                        data_suitability=rules.get('data_suitability', 0.5),
                        visual_effectiveness=rules.get('visual_effectiveness', 0.5),
                        user_preference=score
                    )
                    
                    # 生成推荐配置
                    recommendation.recommended_config = self._generate_recommended_config(
                        chart_type, data_features, data.columns.tolist()
                    )
                    
                    recommendations.append(recommendation)
            
            # 按推荐度排序
            recommendations.sort(key=lambda x: x.confidence, reverse=True)
            
            self.logger.info(f"为数据推荐了 {len(recommendations)} 种图表类型")
            return recommendations
            
        except Exception as e:
            self.logger.error(f"推荐图表类型失败: {str(e)}")
            return []
    
    def generate_chart(self, 
                      data: pd.DataFrame, 
                      config: ChartConfig) -> VisualizationResult:
        """
        生成图表
        
        Args:
            data: 数据DataFrame
            config: 图表配置
            
        Returns:
            可视化结果
        """
        try:
            start_time = datetime.datetime.now()
            
            # 检查缓存
            cache_key = self._generate_cache_key(data, config)
            if cache_key in self.chart_cache:
                cached_result = self.chart_cache[cache_key]
                self.logger.info(f"使用缓存的图表: {config.chart_type.value}")
                return cached_result
            
            # 数据预处理
            processed_data = self._preprocess_data_for_chart(data, config)
            
            # 选择可视化库
            library = self._select_visualization_library(config)
            
            # 生成图表
            if config.chart_type in self.chart_generators:
                chart_generator = self.chart_generators[config.chart_type]
                result = chart_generator(processed_data, config, library)
            else:
                raise ValueError(f"不支持的图表类型: {config.chart_type}")
            
            # 计算执行时间
            execution_time = (datetime.datetime.now() - start_time).total_seconds() * 1000
            result.generation_time_ms = execution_time
            result.data_points = len(processed_data)
            
            # 质量评估
            result.visual_quality_score = self._evaluate_visual_quality(result, config)
            result.accessibility_score = self._evaluate_accessibility(result, config)
            result.performance_score = self._evaluate_performance(result)
            
            # 缓存结果
            self.chart_cache[cache_key] = result
            
            self.logger.info(f"生成图表完成: {config.chart_type.value} (耗时: {execution_time:.2f}ms)")
            return result
            
        except Exception as e:
            self.logger.error(f"生成图表失败: {str(e)}")
            return VisualizationResult(
                success=False,
                error_message=str(e),
                chart_type=config.chart_type
            )
    
    def generate_multiple_charts(self, 
                               data: pd.DataFrame, 
                               configs: List[ChartConfig]) -> List[VisualizationResult]:
        """
        批量生成多个图表
        
        Args:
            data: 数据DataFrame
            configs: 图表配置列表
            
        Returns:
            可视化结果列表
        """
        try:
            results = []
            
            for i, config in enumerate(configs):
                self.logger.info(f"生成第 {i+1}/{len(configs)} 个图表: {config.chart_type.value}")
                result = self.generate_chart(data, config)
                results.append(result)
            
            self.logger.info(f"批量生成 {len(configs)} 个图表完成")
            return results
            
        except Exception as e:
            self.logger.error(f"批量生成图表失败: {str(e)}")
            return []
    
    def create_dashboard(self, 
                        data: pd.DataFrame, 
                        chart_configs: List[ChartConfig],
                        dashboard_title: str = "数据分析仪表板",
                        layout: str = "grid") -> VisualizationResult:
        """
        创建仪表板
        
        Args:
            data: 数据DataFrame
            chart_configs: 图表配置列表
            dashboard_title: 仪表板标题
            layout: 布局方式 (grid, tabs, accordion)
            
        Returns:
            仪表板可视化结果
        """
        try:
            start_time = datetime.datetime.now()
            
            # 生成所有图表
            chart_results = self.generate_multiple_charts(data, chart_configs)
            
            # 创建仪表板布局
            if layout == "grid":
                dashboard_html = self._create_grid_dashboard(chart_results, dashboard_title)
            elif layout == "tabs":
                dashboard_html = self._create_tabs_dashboard(chart_results, dashboard_title)
            elif layout == "accordion":
                dashboard_html = self._create_accordion_dashboard(chart_results, dashboard_title)
            else:
                dashboard_html = self._create_grid_dashboard(chart_results, dashboard_title)
            
            # 计算执行时间
            execution_time = (datetime.datetime.now() - start_time).total_seconds() * 1000
            
            result = VisualizationResult(
                success=True,
                chart_type=ChartType.LINE,  # 仪表板没有特定类型
                library_used=VisualizationLibrary.PLOTLY,
                output_data=dashboard_html,
                output_format=OutputFormat.HTML,
                data_points=len(data),
                generation_time_ms=execution_time,
                file_size_bytes=len(dashboard_html.encode('utf-8'))
            )
            
            # 计算平均质量评分
            if chart_results:
                avg_visual_quality = sum(r.visual_quality_score for r in chart_results) / len(chart_results)
                avg_accessibility = sum(r.accessibility_score for r in chart_results) / len(chart_results)
                avg_performance = sum(r.performance_score for r in chart_results) / len(chart_results)
                
                result.visual_quality_score = avg_visual_quality
                result.accessibility_score = avg_accessibility
                result.performance_score = avg_performance
            
            self.logger.info(f"创建仪表板完成: {len(chart_configs)} 个图表 (耗时: {execution_time:.2f}ms)")
            return result
            
        except Exception as e:
            self.logger.error(f"创建仪表板失败: {str(e)}")
            return VisualizationResult(
                success=False,
                error_message=str(e)
            )
    
    def optimize_chart_for_purpose(self, 
                                 data: pd.DataFrame, 
                                 base_config: ChartConfig,
                                 purpose: str = "presentation") -> ChartConfig:
        """
        根据用途优化图表配置
        
        Args:
            data: 数据DataFrame
            base_config: 基础配置
            purpose: 用途 (presentation, publication, web, mobile, print)
            
        Returns:
            优化后的图表配置
        """
        try:
            optimized_config = ChartConfig(**base_config.to_dict())
            
            if purpose == "presentation":
                # 演示用途：大字体，鲜明颜色，简洁布局
                optimized_config.style.font_size = 16
                optimized_config.style.title_font_size = 24
                optimized_config.style.figure_width = 1200
                optimized_config.style.figure_height = 800
                optimized_config.style.apply_theme("default")
                
            elif purpose == "publication":
                # 学术发表：专业配色，标准尺寸，高分辨率
                optimized_config.style.apply_theme("academic")
                optimized_config.style.figure_width = 800
                optimized_config.style.figure_height = 600
                optimized_config.output_format = OutputFormat.SVG
                
            elif purpose == "web":
                # 网页展示：交互式，响应式布局
                optimized_config.style.interactive = True
                optimized_config.style.show_toolbar = True
                optimized_config.output_format = OutputFormat.HTML
                
            elif purpose == "mobile":
                # 移动端：小尺寸，简化元素
                optimized_config.style.figure_width = 400
                optimized_config.style.figure_height = 300
                optimized_config.style.font_size = 10
                optimized_config.style.show_toolbar = False
                
            elif purpose == "print":
                # 打印：高对比度，黑白友好
                optimized_config.style.background_color = "white"
                optimized_config.style.color_palette = [
                    '#000000', '#404040', '#808080', '#c0c0c0', '#ffffff'
                ]
                optimized_config.output_format = OutputFormat.PDF
            
            self.logger.info(f"为 {purpose} 用途优化图表配置")
            return optimized_config
            
        except Exception as e:
            self.logger.error(f"优化图表配置失败: {str(e)}")
            return base_config
    
    def export_chart(self, 
                    result: VisualizationResult, 
                    file_path: str,
                    format: OutputFormat = None) -> bool:
        """
        导出图表到文件
        
        Args:
            result: 可视化结果
            file_path: 文件路径
            format: 输出格式（如果不指定则使用结果中的格式）
            
        Returns:
            是否导出成功
        """
        try:
            export_format = format or result.output_format
            
            if export_format == OutputFormat.HTML:
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write(result.output_data)
                    
            elif export_format == OutputFormat.JSON:
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write(result.output_data)
                    
            elif export_format == OutputFormat.BASE64:
                # 解码base64并保存为图片
                image_data = base64.b64decode(result.output_data)
                with open(file_path, 'wb') as f:
                    f.write(image_data)
            
            else:
                # 其他格式需要重新生成
                self.logger.warning(f"不支持直接导出格式: {export_format}")
                return False
            
            result.file_path = file_path
            self.logger.info(f"图表导出成功: {file_path}")
            return True
            
        except Exception as e:
            self.logger.error(f"导出图表失败: {str(e)}")
            return False
    
    def _analyze_data_features(self, data: pd.DataFrame) -> Dict[str, Any]:
        """分析数据特征"""
        features = {
            'row_count': len(data),
            'column_count': len(data.columns),
            'numeric_columns': [],
            'categorical_columns': [],
            'datetime_columns': [],
            'has_missing_values': data.isnull().any().any(),
            'data_types': {}
        }
        
        for column in data.columns:
            dtype = str(data[column].dtype)
            features['data_types'][column] = dtype
            
            if data[column].dtype in ['int64', 'float64']:
                features['numeric_columns'].append(column)
            elif data[column].dtype == 'object':
                # 检查是否为日期时间
                try:
                    pd.to_datetime(data[column].dropna().iloc[0])
                    features['datetime_columns'].append(column)
                except:
                    features['categorical_columns'].append(column)
            elif 'datetime' in dtype:
                features['datetime_columns'].append(column)
        
        return features
    
    def _calculate_recommendation_score(self, 
                                      chart_type: ChartType, 
                                      data_features: Dict[str, Any],
                                      analysis_goal: str,
                                      user_preferences: Dict[str, Any]) -> float:
        """计算图表推荐评分"""
        score = 0.0
        
        # 基于数据特征的评分
        if chart_type in self.recommendation_rules:
            rules = self.recommendation_rules[chart_type]
            
            # 数据类型适配性
            if 'required_data_types' in rules:
                required_types = rules['required_data_types']
                if 'numeric' in required_types and data_features['numeric_columns']:
                    score += 0.3
                if 'categorical' in required_types and data_features['categorical_columns']:
                    score += 0.3
                if 'datetime' in required_types and data_features['datetime_columns']:
                    score += 0.3
            
            # 数据量适配性
            if 'optimal_data_range' in rules:
                min_rows, max_rows = rules['optimal_data_range']
                row_count = data_features['row_count']
                if min_rows <= row_count <= max_rows:
                    score += 0.2
                elif row_count < min_rows:
                    score += 0.1 * (row_count / min_rows)
                else:
                    score += 0.1 * (max_rows / row_count)
        
        # 基于分析目标的评分
        goal_scores = {
            'comparison': {
                ChartType.BAR: 0.3, ChartType.LINE: 0.2, ChartType.RADAR: 0.2
            },
            'distribution': {
                ChartType.HISTOGRAM: 0.3, ChartType.BOX: 0.2, ChartType.VIOLIN: 0.2
            },
            'relationship': {
                ChartType.SCATTER: 0.3, ChartType.HEATMAP: 0.2, ChartType.LINE: 0.1
            },
            'composition': {
                ChartType.PIE: 0.3, ChartType.TREEMAP: 0.2, ChartType.SUNBURST: 0.2
            },
            'trend': {
                ChartType.LINE: 0.3, ChartType.BAR: 0.1, ChartType.WATERFALL: 0.2
            }
        }
        
        if analysis_goal in goal_scores and chart_type in goal_scores[analysis_goal]:
            score += goal_scores[analysis_goal][chart_type]
        
        # 用户偏好评分
        if 'preferred_chart_types' in user_preferences:
            if chart_type in user_preferences['preferred_chart_types']:
                score += 0.2
        
        return min(1.0, score)
    
    def _generate_recommendation_reason(self, 
                                      chart_type: ChartType, 
                                      data_features: Dict[str, Any],
                                      analysis_goal: str) -> str:
        """生成推荐理由"""
        reasons = []
        
        # 基于图表类型的通用理由
        chart_reasons = {
            ChartType.LINE: "适合展示趋势变化和时间序列数据",
            ChartType.BAR: "适合比较不同类别的数值大小",
            ChartType.SCATTER: "适合探索两个变量之间的关系",
            ChartType.PIE: "适合展示部分与整体的比例关系",
            ChartType.HISTOGRAM: "适合展示数据的分布情况",
            ChartType.BOX: "适合比较多组数据的分布特征",
            ChartType.HEATMAP: "适合展示矩阵数据和相关性"
        }
        
        if chart_type in chart_reasons:
            reasons.append(chart_reasons[chart_type])
        
        # 基于数据特征的理由
        if data_features['numeric_columns'] and chart_type in [ChartType.HISTOGRAM, ChartType.BOX, ChartType.SCATTER]:
            reasons.append(f"数据包含 {len(data_features['numeric_columns'])} 个数值列")
        
        if data_features['categorical_columns'] and chart_type in [ChartType.BAR, ChartType.PIE]:
            reasons.append(f"数据包含 {len(data_features['categorical_columns'])} 个分类列")
        
        if data_features['datetime_columns'] and chart_type == ChartType.LINE:
            reasons.append("数据包含时间序列信息")
        
        # 基于分析目标的理由
        goal_reasons = {
            'comparison': "当前分析目标是比较不同组别",
            'distribution': "当前分析目标是了解数据分布",
            'relationship': "当前分析目标是探索变量关系",
            'composition': "当前分析目标是分析组成结构",
            'trend': "当前分析目标是观察趋势变化"
        }
        
        if analysis_goal in goal_reasons:
            reasons.append(goal_reasons[analysis_goal])
        
        return "；".join(reasons) if reasons else "基于数据特征推荐"    

    def _generate_recommended_config(self, 
                                   chart_type: ChartType, 
                                   data_features: Dict[str, Any],
                                   columns: List[str]) -> ChartConfig:
        """生成推荐的图表配置"""
        config = ChartConfig(chart_type=chart_type)
        
        # 根据数据特征设置默认列
        numeric_cols = data_features.get('numeric_columns', [])
        categorical_cols = data_features.get('categorical_columns', [])
        datetime_cols = data_features.get('datetime_columns', [])
        
        if chart_type in [ChartType.LINE, ChartType.SCATTER]:
            if datetime_cols:
                config.x_column = datetime_cols[0]
                config.x_axis_type = "date"
            elif categorical_cols:
                config.x_column = categorical_cols[0]
                config.x_axis_type = "category"
            elif numeric_cols:
                config.x_column = numeric_cols[0]
            
            if len(numeric_cols) > 1:
                config.y_column = numeric_cols[1] if config.x_column != numeric_cols[1] else numeric_cols[0]
            elif numeric_cols:
                config.y_column = numeric_cols[0]
        
        elif chart_type in [ChartType.BAR, ChartType.PIE]:
            if categorical_cols:
                config.x_column = categorical_cols[0]
            if numeric_cols:
                config.y_column = numeric_cols[0]
        
        elif chart_type == ChartType.HISTOGRAM:
            if numeric_cols:
                config.x_column = numeric_cols[0]
        
        elif chart_type == ChartType.HEATMAP:
            if len(numeric_cols) >= 2:
                config.x_column = numeric_cols[0]
                config.y_column = numeric_cols[1]
        
        return config
    
    def _initialize_recommendation_rules(self) -> Dict[ChartType, Dict[str, Any]]:
        """初始化图表推荐规则"""
        return {
            ChartType.LINE: {
                'required_data_types': ['numeric'],
                'optimal_data_range': (2, 10000),
                'data_suitability': 0.8,
                'visual_effectiveness': 0.9,
                'best_for': ['trend', 'time_series']
            },
            ChartType.BAR: {
                'required_data_types': ['categorical', 'numeric'],
                'optimal_data_range': (1, 50),
                'data_suitability': 0.9,
                'visual_effectiveness': 0.8,
                'best_for': ['comparison', 'categorical']
            },
            ChartType.SCATTER: {
                'required_data_types': ['numeric'],
                'optimal_data_range': (10, 5000),
                'data_suitability': 0.7,
                'visual_effectiveness': 0.8,
                'best_for': ['relationship', 'correlation']
            },
            ChartType.PIE: {
                'required_data_types': ['categorical', 'numeric'],
                'optimal_data_range': (2, 10),
                'data_suitability': 0.6,
                'visual_effectiveness': 0.6,
                'best_for': ['composition', 'proportion']
            },
            ChartType.HISTOGRAM: {
                'required_data_types': ['numeric'],
                'optimal_data_range': (20, 10000),
                'data_suitability': 0.8,
                'visual_effectiveness': 0.7,
                'best_for': ['distribution']
            },
            ChartType.BOX: {
                'required_data_types': ['numeric'],
                'optimal_data_range': (5, 1000),
                'data_suitability': 0.7,
                'visual_effectiveness': 0.8,
                'best_for': ['distribution', 'comparison']
            },
            ChartType.HEATMAP: {
                'required_data_types': ['numeric'],
                'optimal_data_range': (4, 100),
                'data_suitability': 0.6,
                'visual_effectiveness': 0.7,
                'best_for': ['correlation', 'matrix']
            }
        }
    
    def _select_visualization_library(self, config: ChartConfig) -> VisualizationLibrary:
        """选择最适合的可视化库"""
        if config.library != VisualizationLibrary.AUTO:
            return config.library
        
        # 根据图表类型和配置自动选择
        if config.style.interactive:
            return VisualizationLibrary.PLOTLY
        elif config.chart_type in [ChartType.VIOLIN, ChartType.HEATMAP]:
            return VisualizationLibrary.SEABORN
        else:
            return VisualizationLibrary.PLOTLY  # 默认使用Plotly
    
    def _preprocess_data_for_chart(self, data: pd.DataFrame, config: ChartConfig) -> pd.DataFrame:
        """为图表生成预处理数据"""
        processed_data = data.copy()
        
        # 处理缺失值
        if config.x_column and config.x_column in processed_data.columns:
            processed_data = processed_data.dropna(subset=[config.x_column])
        
        if config.y_column and config.y_column in processed_data.columns:
            processed_data = processed_data.dropna(subset=[config.y_column])
        
        # 数据类型转换
        if config.x_axis_type == "date" and config.x_column:
            processed_data[config.x_column] = pd.to_datetime(processed_data[config.x_column])
        
        # 数据排序
        if config.x_column and config.x_axis_type in ["date", "numeric"]:
            processed_data = processed_data.sort_values(config.x_column)
        
        return processed_data
    
    def _generate_cache_key(self, data: pd.DataFrame, config: ChartConfig) -> str:
        """生成缓存键"""
        import hashlib
        
        # 创建数据哈希
        data_hash = hashlib.md5(str(data.values.tobytes()).encode()).hexdigest()[:8]
        
        # 创建配置哈希
        config_str = f"{config.chart_type.value}_{config.x_column}_{config.y_column}_{config.style.theme}"
        config_hash = hashlib.md5(config_str.encode()).hexdigest()[:8]
        
        return f"{data_hash}_{config_hash}"
    
    # 具体图表生成函数
    def _generate_line_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成折线图"""
        try:
            if library == VisualizationLibrary.PLOTLY:
                fig = px.line(
                    data, 
                    x=config.x_column, 
                    y=config.y_column,
                    color=config.color_column,
                    title=config.title
                )
                
                # 应用样式
                fig.update_layout(
                    width=config.style.figure_width,
                    height=config.style.figure_height,
                    font_family=config.style.font_family,
                    font_size=config.style.font_size,
                    title_font_size=config.style.title_font_size,
                    plot_bgcolor=config.style.background_color,
                    showlegend=config.style.show_legend
                )
                
                if config.x_axis_title:
                    fig.update_xaxes(title_text=config.x_axis_title)
                if config.y_axis_title:
                    fig.update_yaxes(title_text=config.y_axis_title)
                
                # 输出结果
                if config.output_format == OutputFormat.HTML:
                    output_data = fig.to_html(include_plotlyjs=True)
                elif config.output_format == OutputFormat.JSON:
                    output_data = fig.to_json()
                else:
                    output_data = fig.to_html(include_plotlyjs=True)
                
                return VisualizationResult(
                    success=True,
                    chart_type=config.chart_type,
                    library_used=library,
                    output_data=output_data,
                    output_format=config.output_format,
                    file_size_bytes=len(output_data.encode('utf-8'))
                )
            
            else:
                # matplotlib实现
                plt.figure(figsize=(config.style.figure_width/100, config.style.figure_height/100))
                
                if config.color_column and config.color_column in data.columns:
                    # 按颜色分组绘制
                    for group_name, group_data in data.groupby(config.color_column):
                        plt.plot(group_data[config.x_column], group_data[config.y_column], 
                                label=group_name, linewidth=2)
                    plt.legend()
                else:
                    plt.plot(data[config.x_column], data[config.y_column], linewidth=2)
                
                plt.title(config.title, fontsize=config.style.title_font_size)
                plt.xlabel(config.x_axis_title or config.x_column, fontsize=config.style.font_size)
                plt.ylabel(config.y_axis_title or config.y_column, fontsize=config.style.font_size)
                plt.grid(True, alpha=0.3)
                
                # 保存为base64
                buffer = io.BytesIO()
                plt.savefig(buffer, format='png', dpi=150, bbox_inches='tight')
                buffer.seek(0)
                image_base64 = base64.b64encode(buffer.getvalue()).decode()
                plt.close()
                
                return VisualizationResult(
                    success=True,
                    chart_type=config.chart_type,
                    library_used=library,
                    output_data=image_base64,
                    output_format=OutputFormat.BASE64,
                    file_size_bytes=len(image_base64)
                )
                
        except Exception as e:
            return VisualizationResult(
                success=False,
                error_message=str(e),
                chart_type=config.chart_type
            )
    
    def _generate_bar_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成柱状图"""
        try:
            if library == VisualizationLibrary.PLOTLY:
                fig = px.bar(
                    data, 
                    x=config.x_column, 
                    y=config.y_column,
                    color=config.color_column,
                    title=config.title
                )
                
                # 应用样式
                fig.update_layout(
                    width=config.style.figure_width,
                    height=config.style.figure_height,
                    font_family=config.style.font_family,
                    font_size=config.style.font_size,
                    title_font_size=config.style.title_font_size,
                    plot_bgcolor=config.style.background_color,
                    showlegend=config.style.show_legend
                )
                
                if config.x_axis_title:
                    fig.update_xaxes(title_text=config.x_axis_title)
                if config.y_axis_title:
                    fig.update_yaxes(title_text=config.y_axis_title)
                
                # 输出结果
                if config.output_format == OutputFormat.HTML:
                    output_data = fig.to_html(include_plotlyjs=True)
                elif config.output_format == OutputFormat.JSON:
                    output_data = fig.to_json()
                else:
                    output_data = fig.to_html(include_plotlyjs=True)
                
                return VisualizationResult(
                    success=True,
                    chart_type=config.chart_type,
                    library_used=library,
                    output_data=output_data,
                    output_format=config.output_format,
                    file_size_bytes=len(output_data.encode('utf-8'))
                )
            
            else:
                # matplotlib实现
                plt.figure(figsize=(config.style.figure_width/100, config.style.figure_height/100))
                
                if config.color_column and config.color_column in data.columns:
                    # 分组柱状图
                    grouped_data = data.groupby([config.x_column, config.color_column])[config.y_column].sum().unstack()
                    grouped_data.plot(kind='bar', ax=plt.gca())
                    plt.legend(title=config.color_column)
                else:
                    plt.bar(data[config.x_column], data[config.y_column])
                
                plt.title(config.title, fontsize=config.style.title_font_size)
                plt.xlabel(config.x_axis_title or config.x_column, fontsize=config.style.font_size)
                plt.ylabel(config.y_axis_title or config.y_column, fontsize=config.style.font_size)
                plt.xticks(rotation=45)
                plt.grid(True, alpha=0.3)
                
                # 保存为base64
                buffer = io.BytesIO()
                plt.savefig(buffer, format='png', dpi=150, bbox_inches='tight')
                buffer.seek(0)
                image_base64 = base64.b64encode(buffer.getvalue()).decode()
                plt.close()
                
                return VisualizationResult(
                    success=True,
                    chart_type=config.chart_type,
                    library_used=library,
                    output_data=image_base64,
                    output_format=OutputFormat.BASE64,
                    file_size_bytes=len(image_base64)
                )
                
        except Exception as e:
            return VisualizationResult(
                success=False,
                error_message=str(e),
                chart_type=config.chart_type
            )
    
    def _generate_scatter_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成散点图"""
        try:
            if library == VisualizationLibrary.PLOTLY:
                fig = px.scatter(
                    data, 
                    x=config.x_column, 
                    y=config.y_column,
                    color=config.color_column,
                    size=config.size_column,
                    title=config.title
                )
                
                # 应用样式
                fig.update_layout(
                    width=config.style.figure_width,
                    height=config.style.figure_height,
                    font_family=config.style.font_family,
                    font_size=config.style.font_size,
                    title_font_size=config.style.title_font_size,
                    plot_bgcolor=config.style.background_color,
                    showlegend=config.style.show_legend
                )
                
                if config.x_axis_title:
                    fig.update_xaxes(title_text=config.x_axis_title)
                if config.y_axis_title:
                    fig.update_yaxes(title_text=config.y_axis_title)
                
                # 输出结果
                if config.output_format == OutputFormat.HTML:
                    output_data = fig.to_html(include_plotlyjs=True)
                elif config.output_format == OutputFormat.JSON:
                    output_data = fig.to_json()
                else:
                    output_data = fig.to_html(include_plotlyjs=True)
                
                return VisualizationResult(
                    success=True,
                    chart_type=config.chart_type,
                    library_used=library,
                    output_data=output_data,
                    output_format=config.output_format,
                    file_size_bytes=len(output_data.encode('utf-8'))
                )
            
            else:
                # matplotlib实现
                plt.figure(figsize=(config.style.figure_width/100, config.style.figure_height/100))
                
                if config.color_column and config.color_column in data.columns:
                    # 按颜色分组
                    for group_name, group_data in data.groupby(config.color_column):
                        plt.scatter(group_data[config.x_column], group_data[config.y_column], 
                                  label=group_name, alpha=0.7)
                    plt.legend()
                else:
                    plt.scatter(data[config.x_column], data[config.y_column], alpha=0.7)
                
                plt.title(config.title, fontsize=config.style.title_font_size)
                plt.xlabel(config.x_axis_title or config.x_column, fontsize=config.style.font_size)
                plt.ylabel(config.y_axis_title or config.y_column, fontsize=config.style.font_size)
                plt.grid(True, alpha=0.3)
                
                # 保存为base64
                buffer = io.BytesIO()
                plt.savefig(buffer, format='png', dpi=150, bbox_inches='tight')
                buffer.seek(0)
                image_base64 = base64.b64encode(buffer.getvalue()).decode()
                plt.close()
                
                return VisualizationResult(
                    success=True,
                    chart_type=config.chart_type,
                    library_used=library,
                    output_data=image_base64,
                    output_format=OutputFormat.BASE64,
                    file_size_bytes=len(image_base64)
                )
                
        except Exception as e:
            return VisualizationResult(
                success=False,
                error_message=str(e),
                chart_type=config.chart_type
            ) 
   
    def _generate_pie_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成饼图"""
        try:
            if library == VisualizationLibrary.PLOTLY:
                fig = px.pie(
                    data, 
                    names=config.x_column, 
                    values=config.y_column,
                    title=config.title
                )
                
                # 应用样式
                fig.update_layout(
                    width=config.style.figure_width,
                    height=config.style.figure_height,
                    font_family=config.style.font_family,
                    font_size=config.style.font_size,
                    title_font_size=config.style.title_font_size,
                    showlegend=config.style.show_legend
                )
                
                # 输出结果
                if config.output_format == OutputFormat.HTML:
                    output_data = fig.to_html(include_plotlyjs=True)
                elif config.output_format == OutputFormat.JSON:
                    output_data = fig.to_json()
                else:
                    output_data = fig.to_html(include_plotlyjs=True)
                
                return VisualizationResult(
                    success=True,
                    chart_type=config.chart_type,
                    library_used=library,
                    output_data=output_data,
                    output_format=config.output_format,
                    file_size_bytes=len(output_data.encode('utf-8'))
                )
            
            else:
                # matplotlib实现
                plt.figure(figsize=(config.style.figure_width/100, config.style.figure_height/100))
                
                plt.pie(data[config.y_column], labels=data[config.x_column], autopct='%1.1f%%')
                plt.title(config.title, fontsize=config.style.title_font_size)
                
                # 保存为base64
                buffer = io.BytesIO()
                plt.savefig(buffer, format='png', dpi=150, bbox_inches='tight')
                buffer.seek(0)
                image_base64 = base64.b64encode(buffer.getvalue()).decode()
                plt.close()
                
                return VisualizationResult(
                    success=True,
                    chart_type=config.chart_type,
                    library_used=library,
                    output_data=image_base64,
                    output_format=OutputFormat.BASE64,
                    file_size_bytes=len(image_base64)
                )
                
        except Exception as e:
            return VisualizationResult(
                success=False,
                error_message=str(e),
                chart_type=config.chart_type
            )
    
    def _generate_histogram(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成直方图"""
        try:
            if library == VisualizationLibrary.PLOTLY:
                fig = px.histogram(
                    data, 
                    x=config.x_column,
                    color=config.color_column,
                    title=config.title,
                    nbins=config.chart_specific_config.get('bins', 30)
                )
                
                # 应用样式
                fig.update_layout(
                    width=config.style.figure_width,
                    height=config.style.figure_height,
                    font_family=config.style.font_family,
                    font_size=config.style.font_size,
                    title_font_size=config.style.title_font_size,
                    plot_bgcolor=config.style.background_color,
                    showlegend=config.style.show_legend
                )
                
                if config.x_axis_title:
                    fig.update_xaxes(title_text=config.x_axis_title)
                fig.update_yaxes(title_text="频次")
                
                # 输出结果
                if config.output_format == OutputFormat.HTML:
                    output_data = fig.to_html(include_plotlyjs=True)
                elif config.output_format == OutputFormat.JSON:
                    output_data = fig.to_json()
                else:
                    output_data = fig.to_html(include_plotlyjs=True)
                
                return VisualizationResult(
                    success=True,
                    chart_type=config.chart_type,
                    library_used=library,
                    output_data=output_data,
                    output_format=config.output_format,
                    file_size_bytes=len(output_data.encode('utf-8'))
                )
            
            else:
                # matplotlib实现
                plt.figure(figsize=(config.style.figure_width/100, config.style.figure_height/100))
                
                bins = config.chart_specific_config.get('bins', 30)
                if config.color_column and config.color_column in data.columns:
                    # 分组直方图
                    for group_name, group_data in data.groupby(config.color_column):
                        plt.hist(group_data[config.x_column], bins=bins, alpha=0.7, label=group_name)
                    plt.legend()
                else:
                    plt.hist(data[config.x_column], bins=bins, alpha=0.7)
                
                plt.title(config.title, fontsize=config.style.title_font_size)
                plt.xlabel(config.x_axis_title or config.x_column, fontsize=config.style.font_size)
                plt.ylabel("频次", fontsize=config.style.font_size)
                plt.grid(True, alpha=0.3)
                
                # 保存为base64
                buffer = io.BytesIO()
                plt.savefig(buffer, format='png', dpi=150, bbox_inches='tight')
                buffer.seek(0)
                image_base64 = base64.b64encode(buffer.getvalue()).decode()
                plt.close()
                
                return VisualizationResult(
                    success=True,
                    chart_type=config.chart_type,
                    library_used=library,
                    output_data=image_base64,
                    output_format=OutputFormat.BASE64,
                    file_size_bytes=len(image_base64)
                )
                
        except Exception as e:
            return VisualizationResult(
                success=False,
                error_message=str(e),
                chart_type=config.chart_type
            )
    
    def _generate_box_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成箱线图"""
        try:
            if library == VisualizationLibrary.PLOTLY:
                fig = px.box(
                    data, 
                    x=config.x_column, 
                    y=config.y_column,
                    color=config.color_column,
                    title=config.title
                )
                
                # 应用样式
                fig.update_layout(
                    width=config.style.figure_width,
                    height=config.style.figure_height,
                    font_family=config.style.font_family,
                    font_size=config.style.font_size,
                    title_font_size=config.style.title_font_size,
                    plot_bgcolor=config.style.background_color,
                    showlegend=config.style.show_legend
                )
                
                if config.x_axis_title:
                    fig.update_xaxes(title_text=config.x_axis_title)
                if config.y_axis_title:
                    fig.update_yaxes(title_text=config.y_axis_title)
                
                # 输出结果
                if config.output_format == OutputFormat.HTML:
                    output_data = fig.to_html(include_plotlyjs=True)
                elif config.output_format == OutputFormat.JSON:
                    output_data = fig.to_json()
                else:
                    output_data = fig.to_html(include_plotlyjs=True)
                
                return VisualizationResult(
                    success=True,
                    chart_type=config.chart_type,
                    library_used=library,
                    output_data=output_data,
                    output_format=config.output_format,
                    file_size_bytes=len(output_data.encode('utf-8'))
                )
            
            else:
                # seaborn实现
                plt.figure(figsize=(config.style.figure_width/100, config.style.figure_height/100))
                
                if config.x_column and config.y_column:
                    sns.boxplot(data=data, x=config.x_column, y=config.y_column, hue=config.color_column)
                else:
                    sns.boxplot(data=data[config.y_column or config.x_column])
                
                plt.title(config.title, fontsize=config.style.title_font_size)
                if config.x_axis_title:
                    plt.xlabel(config.x_axis_title, fontsize=config.style.font_size)
                if config.y_axis_title:
                    plt.ylabel(config.y_axis_title, fontsize=config.style.font_size)
                
                # 保存为base64
                buffer = io.BytesIO()
                plt.savefig(buffer, format='png', dpi=150, bbox_inches='tight')
                buffer.seek(0)
                image_base64 = base64.b64encode(buffer.getvalue()).decode()
                plt.close()
                
                return VisualizationResult(
                    success=True,
                    chart_type=config.chart_type,
                    library_used=library,
                    output_data=image_base64,
                    output_format=OutputFormat.BASE64,
                    file_size_bytes=len(image_base64)
                )
                
        except Exception as e:
            return VisualizationResult(
                success=False,
                error_message=str(e),
                chart_type=config.chart_type
            )
    
    def _generate_heatmap(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成热力图"""
        try:
            # 准备热力图数据
            if config.x_column and config.y_column:
                # 透视表形式
                heatmap_data = data.pivot_table(
                    values=config.chart_specific_config.get('value_column', data.select_dtypes(include=[np.number]).columns[0]),
                    index=config.y_column,
                    columns=config.x_column,
                    aggfunc='mean'
                )
            else:
                # 相关性矩阵
                numeric_columns = data.select_dtypes(include=[np.number]).columns
                heatmap_data = data[numeric_columns].corr()
            
            if library == VisualizationLibrary.PLOTLY:
                fig = px.imshow(
                    heatmap_data,
                    title=config.title,
                    color_continuous_scale='RdYlBu_r'
                )
                
                # 应用样式
                fig.update_layout(
                    width=config.style.figure_width,
                    height=config.style.figure_height,
                    font_family=config.style.font_family,
                    font_size=config.style.font_size,
                    title_font_size=config.style.title_font_size
                )
                
                # 输出结果
                if config.output_format == OutputFormat.HTML:
                    output_data = fig.to_html(include_plotlyjs=True)
                elif config.output_format == OutputFormat.JSON:
                    output_data = fig.to_json()
                else:
                    output_data = fig.to_html(include_plotlyjs=True)
                
                return VisualizationResult(
                    success=True,
                    chart_type=config.chart_type,
                    library_used=library,
                    output_data=output_data,
                    output_format=config.output_format,
                    file_size_bytes=len(output_data.encode('utf-8'))
                )
            
            else:
                # seaborn实现
                plt.figure(figsize=(config.style.figure_width/100, config.style.figure_height/100))
                
                sns.heatmap(heatmap_data, annot=True, cmap='RdYlBu_r', center=0)
                plt.title(config.title, fontsize=config.style.title_font_size)
                
                # 保存为base64
                buffer = io.BytesIO()
                plt.savefig(buffer, format='png', dpi=150, bbox_inches='tight')
                buffer.seek(0)
                image_base64 = base64.b64encode(buffer.getvalue()).decode()
                plt.close()
                
                return VisualizationResult(
                    success=True,
                    chart_type=config.chart_type,
                    library_used=library,
                    output_data=image_base64,
                    output_format=OutputFormat.BASE64,
                    file_size_bytes=len(image_base64)
                )
                
        except Exception as e:
            return VisualizationResult(
                success=False,
                error_message=str(e),
                chart_type=config.chart_type
            )
    
    # 简化实现其他图表类型（占位符）
    def _generate_violin_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成小提琴图"""
        return self._generate_placeholder_chart(config, "小提琴图功能开发中")
    
    def _generate_treemap(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成树状图"""
        return self._generate_placeholder_chart(config, "树状图功能开发中")
    
    def _generate_sunburst(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成旭日图"""
        return self._generate_placeholder_chart(config, "旭日图功能开发中")
    
    def _generate_radar_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成雷达图"""
        return self._generate_placeholder_chart(config, "雷达图功能开发中")
    
    def _generate_waterfall_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成瀑布图"""
        return self._generate_placeholder_chart(config, "瀑布图功能开发中")
    
    def _generate_gantt_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成甘特图"""
        return self._generate_placeholder_chart(config, "甘特图功能开发中")
    
    def _generate_network_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成网络图"""
        return self._generate_placeholder_chart(config, "网络图功能开发中")
    
    def _generate_sankey_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成桑基图"""
        return self._generate_placeholder_chart(config, "桑基图功能开发中")
    
    def _generate_funnel_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成漏斗图"""
        return self._generate_placeholder_chart(config, "漏斗图功能开发中")
    
    def _generate_gauge_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成仪表盘"""
        return self._generate_placeholder_chart(config, "仪表盘功能开发中")
    
    def _generate_candlestick_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成K线图"""
        return self._generate_placeholder_chart(config, "K线图功能开发中")
    
    def _generate_surface_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成3D表面图"""
        return self._generate_placeholder_chart(config, "3D表面图功能开发中")
    
    def _generate_mesh_chart(self, data: pd.DataFrame, config: ChartConfig, library: VisualizationLibrary) -> VisualizationResult:
        """生成3D网格图"""
        return self._generate_placeholder_chart(config, "3D网格图功能开发中")
    
    def _generate_placeholder_chart(self, config: ChartConfig, message: str) -> VisualizationResult:
        """生成占位符图表"""
        html_content = f"""
        <div style="width: {config.style.figure_width}px; height: {config.style.figure_height}px; 
                    display: flex; align-items: center; justify-content: center; 
                    border: 2px dashed #ccc; background-color: #f9f9f9;">
            <div style="text-align: center;">
                <h3>{config.title or config.chart_type.value}</h3>
                <p>{message}</p>
            </div>
        </div>
        """
        
        return VisualizationResult(
            success=True,
            chart_type=config.chart_type,
            library_used=VisualizationLibrary.PLOTLY,
            output_data=html_content,
            output_format=OutputFormat.HTML,
            file_size_bytes=len(html_content.encode('utf-8'))
        )
    
    # 仪表板创建函数
    def _create_grid_dashboard(self, chart_results: List[VisualizationResult], title: str) -> str:
        """创建网格布局仪表板"""
        html_parts = [f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>{title}</title>
            <style>
                body {{ font-family: Arial, sans-serif; margin: 20px; }}
                .dashboard-title {{ text-align: center; margin-bottom: 30px; }}
                .chart-grid {{ display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 20px; }}
                .chart-container {{ border: 1px solid #ddd; padding: 10px; border-radius: 5px; }}
            </style>
        </head>
        <body>
            <h1 class="dashboard-title">{title}</h1>
            <div class="chart-grid">
        """]
        
        for i, result in enumerate(chart_results):
            if result.success:
                html_parts.append(f"""
                <div class="chart-container">
                    <h3>图表 {i+1}: {result.chart_type.value}</h3>
                    {result.output_data}
                </div>
                """)
        
        html_parts.append("""
            </div>
        </body>
        </html>
        """)
        
        return "".join(html_parts)
    
    def _create_tabs_dashboard(self, chart_results: List[VisualizationResult], title: str) -> str:
        """创建标签页布局仪表板"""
        html_parts = [f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>{title}</title>
            <style>
                body {{ font-family: Arial, sans-serif; margin: 20px; }}
                .dashboard-title {{ text-align: center; margin-bottom: 30px; }}
                .tabs {{ display: flex; border-bottom: 1px solid #ccc; }}
                .tab {{ padding: 10px 20px; cursor: pointer; border: none; background: none; }}
                .tab.active {{ background-color: #f0f0f0; border-bottom: 2px solid #007cba; }}
                .tab-content {{ display: none; padding: 20px; }}
                .tab-content.active {{ display: block; }}
            </style>
            <script>
                function showTab(tabId) {{
                    var tabs = document.querySelectorAll('.tab');
                    var contents = document.querySelectorAll('.tab-content');
                    
                    tabs.forEach(tab => tab.classList.remove('active'));
                    contents.forEach(content => content.classList.remove('active'));
                    
                    document.getElementById('tab-' + tabId).classList.add('active');
                    document.getElementById('content-' + tabId).classList.add('active');
                }}
            </script>
        </head>
        <body>
            <h1 class="dashboard-title">{title}</h1>
            <div class="tabs">
        """]
        
        # 添加标签页按钮
        for i, result in enumerate(chart_results):
            if result.success:
                active_class = "active" if i == 0 else ""
                html_parts.append(f"""
                <button class="tab {active_class}" id="tab-{i}" onclick="showTab({i})">
                    图表 {i+1}
                </button>
                """)
        
        html_parts.append("</div>")
        
        # 添加标签页内容
        for i, result in enumerate(chart_results):
            if result.success:
                active_class = "active" if i == 0 else ""
                html_parts.append(f"""
                <div class="tab-content {active_class}" id="content-{i}">
                    <h3>{result.chart_type.value}</h3>
                    {result.output_data}
                </div>
                """)
        
        html_parts.append("""
        </body>
        </html>
        """)
        
        return "".join(html_parts)
    
    def _create_accordion_dashboard(self, chart_results: List[VisualizationResult], title: str) -> str:
        """创建手风琴布局仪表板"""
        html_parts = [f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>{title}</title>
            <style>
                body {{ font-family: Arial, sans-serif; margin: 20px; }}
                .dashboard-title {{ text-align: center; margin-bottom: 30px; }}
                .accordion {{ border: 1px solid #ddd; }}
                .accordion-item {{ border-bottom: 1px solid #ddd; }}
                .accordion-header {{ padding: 15px; background-color: #f5f5f5; cursor: pointer; }}
                .accordion-header:hover {{ background-color: #e5e5e5; }}
                .accordion-content {{ padding: 20px; display: none; }}
                .accordion-content.active {{ display: block; }}
            </style>
            <script>
                function toggleAccordion(index) {{
                    var content = document.getElementById('accordion-content-' + index);
                    var isActive = content.classList.contains('active');
                    
                    // 关闭所有手风琴项
                    var allContents = document.querySelectorAll('.accordion-content');
                    allContents.forEach(c => c.classList.remove('active'));
                    
                    // 如果当前项未激活，则激活它
                    if (!isActive) {{
                        content.classList.add('active');
                    }}
                }}
            </script>
        </head>
        <body>
            <h1 class="dashboard-title">{title}</h1>
            <div class="accordion">
        """]
        
        for i, result in enumerate(chart_results):
            if result.success:
                html_parts.append(f"""
                <div class="accordion-item">
                    <div class="accordion-header" onclick="toggleAccordion({i})">
                        <h3>图表 {i+1}: {result.chart_type.value}</h3>
                    </div>
                    <div class="accordion-content" id="accordion-content-{i}">
                        {result.output_data}
                    </div>
                </div>
                """)
        
        html_parts.append("""
            </div>
        </body>
        </html>
        """)
        
        return "".join(html_parts)
    
    # 质量评估函数
    def _evaluate_visual_quality(self, result: VisualizationResult, config: ChartConfig) -> float:
        """评估视觉质量"""
        score = 70.0  # 基础分
        
        # 标题和标签完整性
        if config.title:
            score += 10
        if config.x_axis_title:
            score += 5
        if config.y_axis_title:
            score += 5
        
        # 样式配置
        if config.style.theme != "default":
            score += 5
        
        # 交互性
        if config.style.interactive:
            score += 5
        
        return min(100.0, score)
    
    def _evaluate_accessibility(self, result: VisualizationResult, config: ChartConfig) -> float:
        """评估可访问性"""
        score = 60.0  # 基础分
        
        # 颜色对比度
        if config.style.theme == "academic":
            score += 15
        
        # 字体大小
        if config.style.font_size >= 12:
            score += 10
        
        # 图例和标签
        if config.style.show_legend:
            score += 10
        
        # 输出格式
        if result.output_format in [OutputFormat.SVG, OutputFormat.HTML]:
            score += 5
        
        return min(100.0, score)
    
    def _evaluate_performance(self, result: VisualizationResult) -> float:
        """评估性能"""
        score = 100.0
        
        # 生成时间评分
        if result.generation_time_ms > 5000:  # 超过5秒
            score -= 30
        elif result.generation_time_ms > 2000:  # 超过2秒
            score -= 15
        elif result.generation_time_ms > 1000:  # 超过1秒
            score -= 5
        
        # 文件大小评分
        if result.file_size_bytes > 5 * 1024 * 1024:  # 超过5MB
            score -= 20
        elif result.file_size_bytes > 1 * 1024 * 1024:  # 超过1MB
            score -= 10
        
        return max(0.0, score)